import pygame
from typing import Optional, Callable

class Transition:
    def __init__(self, duration: float, on_complete: Optional[Callable] = None):
        self.duration = duration
        self.elapsed = 0
        self.on_complete = on_complete
        self.completed = False
    
    def update(self, dt: float) -> bool:
        if self.completed:
            return True
            
        self.elapsed += dt
        if self.elapsed >= self.duration:
            self.completed = True
            if self.on_complete:
                self.on_complete()
            return True
        return False
    
    def get_progress(self) -> float:
        return min(1.0, self.elapsed / self.duration)

class FadeTransition(Transition):
    def draw(self, screen: pygame.Surface):
        progress = self.get_progress()
        alpha = int(255 * progress)
        overlay = pygame.Surface(screen.get_size(), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, alpha))
        screen.blit(overlay, (0, 0))

class SlideTransition(Transition):
    def __init__(self, duration: float, direction: str = "right", 
                 on_complete: Optional[Callable] = None):
        super().__init__(duration, on_complete)
        self.direction = direction
    
    def draw(self, screen: pygame.Surface):
        progress = self.get_progress()
        width, height = screen.get_size()
        
        if self.direction == "right":
            offset = int(width * progress)
            pygame.draw.rect(screen, (0, 0, 0), 
                           (0, 0, offset, height))
        elif self.direction == "left":
            offset = int(width * (1 - progress))
            pygame.draw.rect(screen, (0, 0, 0), 
                           (offset, 0, width - offset, height))

class TransitionManager:
    def __init__(self):
        self.current_transition: Optional[Transition] = None
    
    def start_transition(self, transition: Transition):
        self.current_transition = transition
    
    def update(self, dt: float):
        if self.current_transition:
            if self.current_transition.update(dt):
                self.current_transition = None
    
    def draw(self, screen: pygame.Surface):
        if self.current_transition:
            self.current_transition.draw(screen) 